package com.itkm.service.impl;

import com.itkm.entity.AuthorityEnum;
import com.itkm.entity.Customer;
import com.itkm.repository.CustomerAuthorityRepository;
import com.itkm.repository.CustomerRepository;
import com.itkm.service.CustomerService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Optional;
import java.util.function.Supplier;

@Service
public class CustomerServiceImpl implements CustomerService {
    @Resource
    private CustomerRepository customerRepository;
    @Resource
    private CustomerAuthorityRepository customerAuthorityRepository;
    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public Optional<Customer> getCustomer(String username) {
        Customer customer = retrieveCache("comment_" + username, Customer.class,
                () -> customerRepository.findByUsername(username));
        return Optional.ofNullable(customer);
    }


    @Override
    public String getCustomerAuthority(String username) {
        String auth = retrieveCache("authorities_" + username, String.class,
                () -> customerAuthorityRepository.findAuthByUsername(username).getAuthority());
        return auth != null ? auth : AuthorityEnum.UNKNOWN.getAuthority();
    }

    /**
     * 检索 或 设置 Redis
     *
     * @param key        Redis缓存主键
     * @param clazz      Redis缓存值类型
     * @param retrieveDb 查询数据库
     * @return 检索信息
     */
    private <T> T retrieveCache(String key, Class<T> clazz, Supplier<T> retrieveDb) {
        return Optional.of(key).map(redisTemplate.opsForValue()::get)
                .map(clazz::cast)
                .orElseGet(() -> {
                    T t = retrieveDb.get();
                    redisTemplate.opsForValue().set(key, t);
                    return t;
                });

    }
}
